// ==UserScript==
// @name         星悦产码
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  星悦产码
// @author       xxx
// @match        https://ops.9hlk5.com/
// @grant        GM_addStyle
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// ==/UserScript==


(function () {
    'use strict';


    function addXMLRequestCallback(callback) {
        // 是一个劫持的函数
        var oldSend, oldOpen, i;
        if (XMLHttpRequest.callbacks) {
            // we've already overridden send() so just add the callback
            XMLHttpRequest.callbacks.push(callback);
        } else {
            // create a callback queue
            XMLHttpRequest.callbacks = [callback];

            // 记录 open 的 url/method —— 新增
            oldOpen = XMLHttpRequest.prototype.open;
            XMLHttpRequest.prototype.open = function (method, url) {
                this._method = method;
                this._url = url;
                return oldOpen.apply(this, arguments);
            };

            // store the native send()
            oldSend = XMLHttpRequest.prototype.send;
            // override the native send()
            XMLHttpRequest.prototype.send = function () {
                // 允许回调设置 this._rewriteBody 来改写 body —— 新增
                var args = arguments;
                for (i = 0; i < XMLHttpRequest.callbacks.length; i++) {
                    XMLHttpRequest.callbacks[i](this);
                }
                if (typeof this._rewriteBody === "function") {
                    try {
                        args[0] = this._rewriteBody.call(this, args[0]);
                    } catch (e) { /* 静默忽略 */ }
                }
                return oldSend.apply(this, args);
            };
        }
    }



    // e.g.
    addXMLRequestCallback(function (xhr) {
        // ★ 新增：命中指定接口时改写请求体（JSON / x-www-form-urlencoded / FormData 均可）
        xhr._rewriteBody = function (origBody) {
            if (String(this._url) === "/api/v1/system/prefabs") {
                // JSON
                if (typeof origBody === "string") {
                    var json = JSON.parse(origBody || "{}");
                    // 在这里写你的改写规则 —— 示例：
                    if (json?.type) {
                        json.type = 1
                        if (json.activityUrl?.includes("pay.qq.com")) {
                            json.activityUrl = "https://pay.qq.com/h5/index.shtml"
                        }
                        if (json.activityUrl?.includes("xinyue.qq.com")) {
                            json.activityUrl = "https://xinyue.qq.com"
                        }
                        return JSON.stringify(json);
                    }

                }

            }
            return origBody; // 其他请求不改
        };

        // 调用劫持函数，填入一个function的回调函数
        // 回调函数监听了对xhr调用了监听load状态，并且在触发的时候再次调用一个function，进行一些数据的劫持以及修改
        xhr.addEventListener("load", function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                if (xhr.responseURL == "https://ops.9hlk5.com/api/v1/system/prefab-urls") {
                    //添加产码按钮
                }
                if (xhr.responseURL == "https://ops.9hlk5.com/api/v1/system/prefabs") {

                    //添加产码按钮
                    let parsedData = JSON.parse(xhr.responseText)
                    if (parsedData.data == null) {
                        console.log(xhr.responseText);
                    } else {
                        GM_setValue("gameUserData", parsedData)
                    }
                }
                console.log(xhr.responseURL);
            }
        });
    });

    // const result = {
    //     openid: parsedData.data.channelAccount.openid,
    //     proof: parsedData.data.proof,
    //     amount: parsedData.data.amount,
    //     prefabUrl: parsedData.data.prefabUrl || "mqqapi://forward/url?version=1&src_type=web&url_prefix=aHR0cHM6Ly9teXVuLnRlbnBheS5jb20vbXFxL3BheS9pbmRleC5zaHRtbD9fd3Y9MTAyNyZhcHBfanVtcD0xJnQ9NU01NWI2YmY1OTA3NGE4MWQzZGZmZDM5MWFhYjE2N2Ymc2NoZW1hPSZzY2hlbWFfdXJsPSZvZmZlcmlkPTE0NTAwMDAyMzg=",
    //     upstreamNo: "-APPDJ118196-20250228-Ni70DIDgRea3",
    //     upstreamPayNo: "qqpro_20250228984964652",
    //     nonce: "984964652",
    //     payMethod: parsedData.data.payMethod,
    //     payMode: parsedData.data.payMode,
    //     tokenId: "5M55b6bf59074a81d3dffd391aab167f"
    // };




    // 1. 监听 `产码` 按钮是否出现
    function waitForElements(selector, callback) {
        let interval = setInterval(() => {
            let elements = document.querySelectorAll(selector);
            if (elements.length > 0) {
                clearInterval(interval);
                callback(elements);
            }
        }, 500);
    }

    // 2. 添加 `上传码` 按钮
    function addUploadButton(buttons) {
        buttons.forEach(button => {
            if (!button.dataset.uploadAdded) {  // 防止重复添加
                button.dataset.uploadAdded = "true";
                let uploadBtn = document.createElement("a");
                uploadBtn.innerText = "上传";
                uploadBtn.href = "javascript:void(0);";
                uploadBtn.className = "el-button el-button--primary el-button--default";
                uploadBtn.title = "上传";
                uploadBtn.onclick = () => showUploadDialog();
                button.parentNode.insertBefore(uploadBtn, button);
            }
        });
    }

    // 3. 显示上传码弹窗
    function showUploadDialog() {
        let dialog = document.createElement("div");
        dialog.classList.add("upload-dialog");
        console.log(GM_getValue("gameUserData"), "<------GM_getValue");
        dialog.innerHTML = `
            <div class="upload-dialog-content">
                <span class="close-btn">&times;</span>
                <h2>产码上传</h2>
                <label>账号参数URL</label>
                <textarea id="upload-url" placeholder="请输入产码参数">
                  ` + (GM_getValue("gameUserData") !== undefined ? JSON.stringify(GM_getValue("gameUserData")) : "") + `
                </textarea>
                <label>订单参数</label>
                <textarea id="upload-order" placeholder="请输入订单参数"></textarea>
                <div class="dialog-buttons">
                    <button id="confirm-upload">确认</button>
                    <button id="cancel-upload">取消</button>
                </div>
            </div>
        `;

        document.body.appendChild(dialog);

        // 关闭弹窗
        dialog.querySelector(".close-btn").onclick = () => dialog.remove();
        dialog.querySelector("#cancel-upload").onclick = () => dialog.remove();

        // 确认上传
        dialog.querySelector("#confirm-upload").onclick = () => {

            // let parsedData = GM_getValue("gameUserData");
            let parsedData = JSON.parse(document.getElementById("upload-url").value);
            let orderParam = document.getElementById("upload-order").value;

            if (!parsedData || !orderParam) {
                alert("请输入完整信息！");
                return;
            }

            //
            let parseOrderParam = JSON.parse(orderParam)
            let upstreamNo = parseOrderParam?.info?.portal_serial_no
            let upstreamPayNo = parseOrderParam?.qqwallet_info?.qqwallet_order_id
            let nonce = parseOrderParam?.qqwallet_info?.qqwallet_nonce
            let tokenId = parseOrderParam?.qqwallet_info?.qqwallet_tokenId
            let qqurl = `https://myun.tenpay.com/mqq/pay/index.shtml?_wv=1027&app_jump=1&t=${tokenId}&schema=&schema_url=&offerid=1450000238`
            // base64 编码
            let encodedData = btoa(unescape(encodeURIComponent(qqurl)));



            // 解析 gameUserData
            const result = {
                openid: parsedData.data.channelAccount.openid,
                proof: parsedData.data.proof,
                amount: parsedData.data.amount,
                prefabUrl: `mqqapi://forward/url?version=1&src_type=web&url_prefix=${encodedData}`,
                upstreamNo: upstreamNo,
                upstreamPayNo: upstreamPayNo,
                nonce: nonce,
                payMethod: parsedData.data.payMethod,
                payMode: parsedData.data.payMode,
                tokenId: tokenId
            };
            // 构造 body
            // let body = `aid=${aid}&key=${key}&base64Str=${encodeURIComponent(encodedData)}`;
            // 发送 POST 请求
            const url = "https://ops.9hlk5.com/api/v1/system/prefabs";
            sendPatchRequest(url, result);
            dialog.remove();
        };
    }

    function sendPatchRequest(url, body) {
        console.log("发送请求到:", url);
        console.log("请求体:", JSON.stringify(body, null, 2));

        GM_xmlhttpRequest({
            method: "PATCH",
            url: url,
            headers: {
                "content-length": JSON.stringify(body).length,
                "sec-ch-ua": "\"Not-A.Brand\";v=\"99\", \"Chromium\";v=\"124\"",
                "accept": "application/json, text/plain, */*",
                "content-type": "application/json",
                "sec-ch-ua-mobile": "?0",
                "authorization": "Bearer OLFEk4LBp6mM0e2DC8DHBZoneqB+pxc0Gb7Z2rewHEreBY11zZM8IUm0RMLUt8dX/DdCaBgWTgTxY6LBGQzlm4tiEwbkMXh8HknXx0x5NL1QCIEQQJs3ed4nffddtzKVN68JvZHDwNeF9DtSOFqpKw==",
                "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) edge/1.3.7 Chrome/124.0.6367.119 Electron/30.0.3 Safari/537.36",
                "sec-ch-ua-platform": "\"Windows\"",
                "origin": "https://ops.9hlk5.com",
                "sec-fetch-site": "same-origin",
                "sec-fetch-mode": "cors",
                "sec-fetch-dest": "empty",
                "referer": "https://ops.9hlk5.com/",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "zh-CN",
                "cookie": "token=OLFEk4LBp6mM0e2DC8DHBZoneqB+pxc0Gb7Z2rewHEreBY11zZM8IUm0RMLUt8dX/DdCaBgWTgTxY6LBGQzlm4tiEwbkMXh8HknXx0x5NL1QCIEQQJs3ed4nffddtzKVN68JvZHDwNeF9DtSOFqpKw==; username=tgg010",
                "priority": "u=1, i",
            },
            data: JSON.stringify(body),
            onload: function (response) {
                console.log("请求成功！服务器返回：", response.responseText);
                alert("请求成功！服务器返回：" + response.responseText);
            },
            onerror: function (error) {
                console.error("请求失败！", error);
                alert("请求失败！请检查网络或服务器状态");
            }
        });
    }


    // 4. 添加样式
    GM_addStyle(`
        .upload-code-btn {
            margin-right: 5px;
            background: #007bff;
            color: white !important;
            border: none;
            padding: 5px 10px;
            cursor: pointer;
            border-radius: 4px;
            text-decoration: none;
        }
        .upload-code-btn:hover {
            background: #0056b3;
        }
        .upload-dialog {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            border-radius: 8px;
            z-index: 1000;
            width: 750px;
        }
        .upload-dialog-content {
            display: flex;
            flex-direction: column;
        }
        .upload-dialog-content label {
            margin-top: 10px;
        }
        .upload-dialog-content input, .upload-dialog-content textarea {
            height: 280px;
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        .dialog-buttons {
            display: flex;
            justify-content: space-between;
            margin-top: 15px;
        }
        .dialog-buttons button {
            padding: 5px 10px;
            border: none;
            cursor: pointer;
            border-radius: 4px;
        }
        #confirm-upload {
            background: #28a745;
            color: white;
        }
        #confirm-upload:hover {
            background: #218838;
        }
        #cancel-upload {
            background: #dc3545;
            color: white;
        }
        #cancel-upload:hover {
            background: #c82333;
        }
        .close-btn {
            position: absolute;
            top: 5px;
            right: 10px;
            cursor: pointer;
            font-size: 18px;
        }
    `);

    // 5. 监测 `产码` 按钮
    waitForElements("span.el-dropdown-link.el-tooltip__trigger.el-tooltip__trigger", addUploadButton);
})();
